import { Directive, DirectiveBinding } from "vue";

interface DebounceBinding extends DirectiveBinding {
  value: (...args: any[]) => void;
  arg?: string;
  modifiers: {
    immediate?: boolean;
  };
}
interface ThrottleElement extends HTMLElement {
  _debouncedFn?: (...args: any[]) => void;
}
const debounce: Directive = {
  mounted(el: ThrottleElement, binding: DebounceBinding) {
    const { value, arg, modifiers } = binding;
    let delay = 500; // 默认延迟时间

    if (arg) {
      delay = parseInt(arg);
      if (isNaN(delay)) {
        delay = 500;
      }
    }

    const immediate = modifiers.immediate;

    // 确保绑定值是函数
    if (typeof value !== "function") {
      throw new Error("v-debounce directive value must be a function");
    }

    let timeout: ReturnType<typeof setTimeout> | null = null;

    const debouncedFn = (...args: any[]) => {
      if (immediate) {
        // 立即执行版本
        if (!timeout) {
          value(...args);
        }
        if (timeout) clearTimeout(timeout);
        timeout = setTimeout(() => {
          timeout = null;
        }, delay);
      } else {
        // 非立即执行版本
        if (timeout) clearTimeout(timeout);
        timeout = setTimeout(() => {
          value(...args);
        }, delay);
      }
    };

    el._debouncedFn = debouncedFn;
    el.addEventListener("click", debouncedFn);
  },

  beforeUnmount(el: HTMLElement & { _debouncedFn?: (...args: any[]) => void }) {
    if (el._debouncedFn) {
      el.removeEventListener("click", el._debouncedFn);
    }
  },
};

export default debounce;
